package com.qiaoba.auth.filter;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import com.qiaoba.api.auth.constant.SecurityConstant;
import com.qiaoba.api.auth.utils.JwtUtil;
import com.qiaoba.auth.properties.AuthConfigProperties;
import com.qiaoba.common.base.order.GlobalFilterOder;
import com.qiaoba.nosql.redis.service.RedisService;
import com.qiaoba.web.util.ResponseUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 验证Token是否有效
 *
 * @author ailanyin
 * @date 2023-09-16 21:22:13
 */
@Component
@Order(GlobalFilterOder.JWT_VERIFY_FILTER)
@RequiredArgsConstructor
public class JwtVerifyFilter implements Filter {

    private final AuthConfigProperties authConfigProperties;
    private final AntPathMatcher antPathMatcher = new AntPathMatcher();
    private final RedisService redisService;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        String uri = request.getRequestURI();
        // 白名单放行
        for (String whiteUri : authConfigProperties.getWhitelist()) {
            if (antPathMatcher.match(whiteUri, uri)) {
                filterChain.doFilter(servletRequest, servletResponse);
                return;
            }
        }
        // 获取Token
        String token = JwtUtil.getToken(request, true);
        token = redisService.getObject(SecurityConstant.LOGIN_USER_TOKENS_REDIS_KEY + token, String.class);
        // 验证Token
        if (StrUtil.isBlank(token) || !JwtUtil.verify(token)) {
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            ResponseUtil.errorAuth(response, HttpStatus.HTTP_UNAUTHORIZED, SecurityConstant.ACCESS_DENIED);
            return;
        }
        // 放行
        filterChain.doFilter(servletRequest, servletResponse);
    }
}
